/*-----------------------------------------------------------------
 * 	TAB MANAGER
 *-----------------------------------------------------------------*/
ul.Tab = function(){};
/**
 * 
 * @param {Object} element
 * @param {Object} content
 */
ul.Tab.TabView = function ( element, content, popup )
{
	this.element = element;
	this.contentElement = content;
	
	this.popup = popup;
	
	this.popupTrigger = this.createPopupTrigger();
	document.getElementsByTagName("body")[0].appendChild( this.popupTrigger );
};
ul.Tab.TabView.prototype = {
	
	tabs : new Collection(),
	
	eventDispatcher : new EventDispatcher(),
	
	tabUnderFocus : null,
 
 	startIndex:0,
	
	getElement : function ()
	{
		return this.element;
	},
	
	getContentElement : function ()
	{
		return this.contentElement;
	},
	setFocus : function ( tab )
	{
		//alert( "focus on " + tab );
		// First verify if there's already a tab under the focus
		if( this.tabUnderFocus != null )
			this.tabUnderFocus.blur();
		
		// set the new tab under focus
		this.tabUnderFocus = tab;
	
		// notify the tab that it has the focus
		this.tabUnderFocus.focus();
		
		//this.tabs.remove( tab );
		//this.tabs.addAt( 0, tab );
		if( this.tabUnderFocus.element.parentNode == null ||
			hasClass( this.tabUnderFocus.getElement(), CSS.MENUITEM ) )
				this.startIndex = this.tabs.indexOf( this.tabUnderFocus );	

		this.repaint();
		
		// fill the tab view content with the tab content
		this.contentElement.innerHTML = this.tabUnderFocus.getContent();
		
		// fire an event to notify listener that the focus has changed
		this.eventDispatcher.fireEvent ( new Event ( "focusChanged", this ) );
	},
	
	getTabUnderFocus : function ()
	{
		return this.tabUnderFocus;
	},
	
	addTab : function ( tab )
	{
		// can't add the same tab twice
		if (!this.tabs.contains(tab)) 
		{
			// defines the tab view which own the tab 
			tab.setOwner( this );
			
			// adds the tab into the collection
			this.tabs.add(tab);
			//this.element.appendChild( tab.render() );
			tab.render();
			// sets the focus on that new tab
			this.setFocus ( tab );
			
			// fire an event to notify listeners that a tab was added
			this.eventDispatcher.fireEvent ( new Event ( "tabAdded", this ) );
		}
	},
	
	removeTab : function ( tab )
	{
		// can't remove a tab which was not stored in the collection
		if (this.tabs.contains(tab)) 
		{
			// removes the tab from the collection
			this.tabs.remove( tab );
			
			// if the removed tab is under focus
			if( this.tabUnderFocus == tab )
			{
				// taking the first tab in the collection if there is one
				if( this.tabs.size() != 0 ) 
					this.setFocus ( this.tabs.get( 0 ) );
				else // clear the whole tabs content
				{
					this.contentElement.innerHTML = "";
					this.tabUnderFocus = null;
					this.repaint();
				}
				
			}	
			else
				this.repaint();	
				
			tab.release();
			// remove the html part of the tab from the DOM
			//this.element.removeChild( tab.release() );
			
			
			// fire an event to notify listeners that a tab was removed 
			this.eventDispatcher.fireEvent ( new Event ( "tabRemoved", this ) );
		}
	},
 	repaint:function ()
	{
		this.clear();
		this.hidePopup();
		removeClass ( this.popup, CSS.CONSTRAINED );
		
		var tabgroup = document.createElement ( "span" );
		var l = this.tabs.size();
		var sens = (l - this.startIndex < this.startIndex );
		var popupTriggerAdded = false;
		var popupConstrained = false;
		var el;
		this.element.appendChild( tabgroup );
		if( sens )
		{
			var n = l;
			var oldtab;
			var oldmenuitem;
			for( var i = l-1; i >= 0;i--)
			{
				var tab = this.tabs.array[ i ];
				tab.setAsTab();
			
				el = tab.getElement();
				// get the width of the element
				tabgroup.appendChild( el );
				var w =  el.offsetWidth;
				tabgroup.removeChild( el );
				
				if( --n <= this.startIndex && tabgroup.offsetWidth + w < this.element.offsetWidth - 40 ) 
				{
					if(	oldtab )
						tabgroup.insertBefore( el, oldtab );
					else
						tabgroup.appendChild( el );
					 
					oldtab = el;
				}
				else
				{
					if( !popupTriggerAdded )
					{
						this.element.appendChild( this.popupTrigger );
						popupTriggerAdded = true;
					}
					
					tab.setAsMenuItem();
					
					if(	oldmenuitem )
						this.popup.insertBefore( el, oldmenuitem );
					else
						this.popup.appendChild( el );
					
					if( !popupConstrained && this.popup.childNodes.length > 5 )
					{
						addClass ( this.popup, CSS.CONSTRAINED );
						popupConstrained = true;
					}
					
					oldmenuitem = el;
				}
			}
		}
		else
		{
			var i = this.tabs.iterator();
			var n = 0;
			while ( i.hasNext() )
			{
				var tab = i.next();
				tab.setAsTab();
			
				oldel = el;
				el = tab.getElement();
				// get the width of the element
				tabgroup.appendChild( el );
				var w =  el.offsetWidth;
				tabgroup.removeChild( el );

				if( n++ >= this.startIndex && tabgroup.offsetWidth + w < this.element.offsetWidth - 40 ) 
				{
					tabgroup.appendChild( el );
				}
				else
				{
					if( !popupTriggerAdded )
					{
						this.element.appendChild( this.popupTrigger );
						popupTriggerAdded = true;
					}
					tab.setAsMenuItem();
					this.popup.appendChild( el );
					
					if( !popupConstrained && this.popup.childNodes.length > 5 )
					{
						addClass ( this.popup, CSS.CONSTRAINED );
						popupConstrained = true;
					}
				}
			
			}
		}
	},
 	showPopup:function()
	{
		removeClass( this.popup, CSS.HIDDEN ) ;
		addClass( this.popupTrigger, CSS.OPENED ) ;
		this.popupTrigger.onclick = delegate( this, this.hidePopup );
	},
 	hidePopup:function()
	{
		addClass( this.popup, CSS.HIDDEN ) ;
		removeClass( this.popupTrigger, CSS.OPENED ) ;
		this.popupTrigger.onclick = delegate( this, this.showPopup );
	},
 	createPopupTrigger:function()
	{
		var bt = document.createElement( "a" );
		bt.href = "#";
		//bt.appendChild( document.createTextNode (" ") );
		bt.className = CSS.POPUP_TRIGGER;
		bt.onclick = delegate( this, this.showPopup );
		bt.title = bt.alt = "Show hidden tabs";
		
		return bt;
	}, 
 	clear:function ()
	{
		// clearing tabs list
		var a1 = this.element.childNodes;
		var a2 = [];
		var l = a1.length;
		for( var i = 0; i < l; i++ )
		{
			a2[i] = a1[i];
		}
		for( var i in a2 )
		{
			this.element.removeChild( a2[i] );
		}
		
		// clearing popup
		a1 = this.popup.childNodes;
		a2 = [];
		l = a1.length;
		for( var i = 0; i < l; i++ )
		{
			a2[i] = a1[i];
		}
		for( var i in a2 )
		{
			this.popup.removeChild( a2[i] );
		}
	},
	
	getTabById : function ( id )
	{
		var i = this.tabs.iterator();
		
		while ( i.hasNext() )
		{
			var tab = i.next();
			if( tab.getId() == id )
				return tab; 
		}
		return null;
	},
	
	getTabsByName : function ( name )
	{
		var a = new Array();
		var i = this.tabs.iterator();
		
		while ( i.hasNext() )
		{
			var tab = i.next();
			if( tab.getName() == name )
				a.push( tab ); 
		}
		return a;
	},
	
	toString : function ()
	{
		return "TabView(" + this.tabs.size() + ")";
	}
};

/*-----------------------------------------------------------------
 * 	TAB ENTITY
 *-----------------------------------------------------------------*/

/**
 * 
 * @param {Object} file
 */
ul.Tab.TabEntity = function ( file )
{
	this.file = file;
	this.element = null;
}

ul.Tab.TabEntity.prototype = {
	owner : null,
	
	setOwner: function ( owner )
	{
		this.owner = owner;
	},
	
	getName : function ()
	{
		return this.file.getName();	
	},
	setName : function ( name )
	{
		this.file.setName( name );	
		var a = this.element.firstChild.firstChild.firstChild;
		a.removeChild( a.firstChild );
		a.appendChild( document.createTextNode ( name ) );
	},
 
 	getFile : function ()
	{
		return this.file;
	},
	
	getId : function ()
	{
		return this.file.getId();
	},
		
	getElement : function ()
	{
		return this.element;
	},
	
	getContent : function ()
	{
		return this.file.getCache();
	},
 
	render : function ()
	{
		var _owner = this.owner;
		var _self = this;
		
		this.file.setCache( "" );
		var mainDiv = document.createElement ( 'div' );
		mainDiv.innerHTML = ul.Templates.parse( ul.Templates.TAB, 
											 this.getId(),
											 this.getName() );
		
		this.element = mainDiv.firstChild;
		mainDiv.removeChild( this.element );
		return this.element;
	},
	
	release : function ()
	{
		var el = this.element;
		
		this.element = null;
		
		return el;
	},
 
 	notify:function ()
	{
		addClass( this.getElement(), CSS.NOTIFIED );
	},
	
	focus : function ()
	{
		removeClass( this.getElement(), CSS.NOTIFIED );
		addClass( this.getElement(), CSS.SELECTED );
	},
	
	blur : function ()
	{
		this.file.setCache( this.owner.getContentElement().innerHTML );
		removeClass( this.getElement(), CSS.SELECTED );
	},
 
	setAsMenuItem:function()
	{
		addClass( this.getElement(), CSS.MENUITEM );
	},
	setAsTab:function()
	{
		removeClass( this.getElement(), CSS.MENUITEM );
	},
	
	toString : function ()
	{
		return "TabEntity(" + this.getName() + ")";
	}
};
